
// do action seq & move next cstl.. 
// noty status to View 
//   - move nex cstl
//  - mgr user cstl info
//  - : use cur user. 
//  -   only handle cstl operation  
//	- singleton
 
CCstlMgr = function() {
	// this.cstl = [] ;
	this.cstls = [] ;
	this.cur_idx = 0; 
	this.force_stop = false;
	
	var self = this;
	em.cbs.heroupdate.add( function(hs) { self.updateAllHs (hs); });
	em.cbs.warableHpdate.add( function(hs) { self.updateHntingableHs (hs); });

	em.cbs.hntdone.add( function(attinfo) { self.hntdone (attinfo); });

 	// update cstl 's sols '
 	em.cbs.updatesols.add (function(sols) { self.updateSols(sols); });
 		// var this.move1done_dfd = new jQuery.Deferred();

	// clear  prev status  
	em.cbs.startuserchange.add (function() { self.clearAll(); });
	
	// TODO : 이제 remove ?? 
	// if  cstl att is done with  fail code : less control  => set cstl file  to skip 
	em.cbs.autoCstlAttDone.add( function(cstlidx, ret_code) {
		debug.log( self, '====== cur cstl ' + cstlidx + ' done ... ' , ret_code);
		} );
 		
 		
  	this.uiView = undefined;
};


CCstlMgr.ENDOF_DA_ARRAY = 101;
CCstlMgr.ENDOF_CASTLES = 102;
CCstlMgr.ERROR = 109;
CCstlMgr.MIN_REQOVER = 200;



CCstlMgr.prototype = {
		objName: 'CCstlMgr : ',
// temp 
notify_cb: function(type, msg){
	debug.log(this, type, msg);
},

	// param :  view  obj 	
	cstlwave_initialize: function(  ) {
		this.cur_idx = 0; 
		this.force_stop = false;
		

		
/*		<-- acc mgr 에서 처리하도록 함. 
		// register cbs
		em.cbs.userlogin.add( function(type, data) { self.cbGotLogin( type, data);});
*/
		
	},
	
	setView: function(view) {
				this.uiView = view;
	},
	
	// for sp 30 
	setNewUserInfo: function( cstls ) {
		var self = this;		
		this.clearAll();
		
		if ( !cstls ) return;
		// update new info 
		// set each cstl info to cstls instances
		$.each( cstls, function(i, cstl)  {
			if ( ! self.cstls[i] ) {
				self.cstls[i] = new CCstl();
			}
			$.extend ( self.cstls[i], cstl);
			
			// self.cstls[i].setUserCityInfo(cstlinfo);	// // {"id":3070,"name":"\ucc9c\uc0c1\uc131","landtype":3,"x":185,"y":53}, 
			// self.cstls[i].updateRes(res);
			// self.cstls[i].updateSols(sols);
			// self.cstls[i].updateCdlist(cds);
			// self.cstls[i].updateCityInfo(city);
			// self.cstls[i].updateStudies(studies);
			
		});
		this.cur_idx = 0; 
	},
	
	getAllStates: function( states ) {
		var self = this;
		// return cur infos 
		// set each cstl info to cstls instances
		$.each( this.cstls , function(i, cstl)  {
			
			if ( ! states.castles[i] ) states.castles[i] = {};
			$.extend (states.castles[i] , self.cstls[i] );
			// self.cstls[i].setUserCityInfo(cstlinfo);	// // {"id":3070,"name":"\ucc9c\uc0c1\uc131","landtype":3,"x":185,"y":53}, 
			// self.cstls[i].updateRes(res);
			// self.cstls[i].updateSols(sols);
			// self.cstls[i].updateCdlist(cds);
			// self.cstls[i].updateCityInfo(city);
			// self.cstls[i].updateStudies(studies);
			
		});
		return states;
	},	
	// when new user selected 
	clearAll: function() {
		this.cur_idx = 0; //  start with next castle... ++
		this.force_stop = false;	
	
		// delete !!! prev cstls info
		$.each( this.cstls, function(i, cstl)  {
			delete cstl;
		});	
		this.cstls = [];
		
	},
	
		getBlessCnt: function() {
					return this.cstls[this.cur_idx].getBlessCnt();
		},
	
	
	/*
		CB s 
	*/
	
	// hid, endtime 을 유지.
	// hid ,: remove attcking h from  cstl hntings h 에서 제거
	// cost : consume res 
	// trs : reflect to cstl sols 
	
	hntdone: function( attinfo){
		debug.log( this, 1, attinfo);
		// store into cstl 
		this.cstls[this.cur_idx].addHntingInfo(attinfo);
		
/*
				hid: this.genid, 
				o: this.param.tr.o, 
				sec: this.hnt_result[0].secs, 
				endtime: this.returntime,	
*/
		// notify view 
		this.uiView.pushAttInfo(this.cur_idx , attinfo);	
	},
	
	
	
	/*
		auto hnting
	*/
/*
	resetHntingInfo: function(index){
		this.cstls[index].resetHntings();
	},
	*/
	// return  shortest_cstl cstl, & and time 
	
	// return  next  & and time 
	getAutoHntNextTime: function() {
		
		var shortest_cstl = -1; // $.now() + 60*60*1000; // set max current + 1hour  
		var cstlidx = -1;
		var self =this;
		// $.each ( this.cstls, function(i, cstl) {
			
			// att info 를 가져와서, endtime max 와 min 을 계산.
			//temp : first cstl is done.. go next  auto att   
			var cstl = this.cstls[0];
			
			// get all hnting cds ...  not removed !!1 
			var curHntings = cstl.getHntings();
			var hnt = {};		// for return  hnt cd 
			if( ! curHntings || curHntings.length == 0	) {
				return new Date();
			} else {
				
				// pvp rule !!! : endtime of first hnt 
				if (CDB.getCurUserOptions().pvp) {
					// get min end time 
					curHntings.sort( function(a,b) { 
							return a.endtime.getTime() -  b.endtime.getTime() ;
							});
				} else {
					// get max end time 
					curHntings.sort( function(a,b) { 
							return b.endtime.getTime() -  a.endtime.getTime() ;
							});
				}

				// copy : it will cleared by mgr when  return ;
				$.extend( hnt, curHntings[0]);
				
				// clear exipred hnt cds if cd is less than now ...   
				this.cstls[0].clearExpiredHntings();
				
				return hnt.endtime;		
			}
			
		// });
	},
	
	// after login.  by  user info city  
	setUserCstls: function(cstls){
		
		var self = this;
		// delete !!! prev cstls info
		$.each( this.cstls, function(i, cstl)  {
			if (self.cstls[i])
				delete self.cstls[i];
		});	
		this.cstls = [] ;	

		// set each cstl info to cstls instances
		$.each( cstls, function(i, cstl)  {
			if ( ! self.cstls[i] ) {
				self.cstls[i] = new CCstl();
			}
			self.cstls[i].setUserCityInfo(cstl);
				
			// notify  UI 
			self.uiView.setCityInfo(i, cstl);
			
		});

	},
	
	selCurCstl: function(index) {
		this.cur_idx = index;
		
		// update ui 
		this.uiView.setCurCstl(index);
		
	},
	
	getCurCstlIdx: function() {
		return this.cur_idx;
	},

	
	setCastlestoWave: function() {
		this.cstls= CDB.getCurUserCtsl();
	},

	getCurCstl: function() {
		return this.cstls[this.cur_idx];
	},
	
	getCstl: function(index) {
		return this.cstls[index];
	},
	
	// end of cstl... return last cstl
	curCstlID: function() {
		// set valid last index 
		if ( this.cur_idx >= this.cstls.length) 
			this.cur_idx = this.cstls.length -1;
		
		this.cur_idx = (this.cur_idx <0 ) ? 0 : this.cur_idx;
		return this.cstls[ this.cur_idx ].id;
	} ,
		
	registerCstlWaveCB: function ( cbs ) {
		this.success_cb =  cbs.success_cb;
		this.error_cb = cbs.error_cb;
		this.notify_cb = cbs.notify_cb;
		this.notify_cb(10000, ' Done Set  mgr param');
	},

	

	moveCstlAt: function( index , move_type) {

		if ( index  >= this.cstls.length) {
			// error 
			// this.notify_cb(this.cur_idx,' Invalid cstl index ');
			debug.log( this,' Invalid cstl index ' );

			// set to last 
			this.cur_idx = this.cstls.length -1;
			return;
		}
		
		this.cur_idx  = index;
		if ( this.move1done_dfd ) delete this.move1done_dfd;
		this.move1done_dfd = new jQuery.Deferred();
		
		$.when(this.move1done_dfd).then(em.cbs.cstlmove1done.fire, function(){alert('movectsl fail');}, 
					function(msg){ console.log(msg);}	);

		debug.log( this, 'moveCstlAt: move to ' + index );
		
		em.tasks4user.moveCstl( this.cstls[index] , this.move1done_dfd , move_type);
		
	},
	
	
	// move wave interface 
	moveNextCstl: function( ) {
		
		this.cur_idx ++;
			
			// check complete .. 
		if ( this.cur_idx >= this.cstls.length) {

			if ( this.completed_cb )
				this.completed_cb();
			if ( this.notify_cb )				
				this.notify_cb(this.cur_idx,' All castles are all done !!');
				
			// this.success_cb(CCstlMgr.ENDOF_CASTLES);
			em.cbs.cstlwavedone.fire();
			
			// set to last 
			this.cur_idx = this.cstls.length -1;
			return;
		}
		
		
		// check force stop 
		if (this.force_stop) {
			this.error_cb('Forced Stop .. in hnt mgr;');
			return undefined;
		} 
		
		// calll actual move function 
		this.moveCstlAt(this.cur_idx );
		
	},
	

	SetStop: function() {
		this.force_stop = true;
	},
	
	abort: function(){
			// stop !! 
			debug.log(this, 'cb ret error : stop !!  ' );
			var error_code = 1;
			this.error_cb(error_code);
	},
	

	updateRes : function(res) {
		this.cstls[this.cur_idx].updateRes(res);
		// update UI 
		this.uiView.setCstlState( this.cur_idx, this.cstls[this.cur_idx]);
	},
	
	// cit info 
	updateCstl: function(city) {
				// this.notify_cb(8888, 'city info !!' + 	' g: ' + city_res.g  + ' f:' + city_res.f);
		// this.notify_cb(55555,  { cindex : this.cur_idx, castle: this.cstl[this.cur_idx]  });
		
		if ( ! this.cstls[this.cur_idx] ) {
				this.cstls[this.cur_idx] = new CCstl();
		}
		this.cstls[this.cur_idx].updateCityInfo(city);
		
		// this.move1done_dfd.notify("working... ");
		// noty UI view 
		this.uiView.setCstlState(this.cur_idx ,this.cstls[this.cur_idx]);
		em.infoview.showBless(city);
		
	},
	
	// cds : can be undefined 
	updateCdlist: function(cds){

			// store cd list to  this cstl  
			this.cstls[this.cur_idx].updateCdlist(cds); 
			
			// em.util.print_obj(cds);
			
			// notify view : cur cstl 
			this.uiView.setCurCstl(this.cur_idx);
			
			// noty  with updated cds in cstl 
			this.uiView.updateCDs(this.cur_idx,  this.cstls[this.cur_idx].getCds() );

	},



	// check type, target list is compleated at cur cstl 
	bCompleteCdlist: function( type, target) {
		
		var check_cds = this.cstls[this.cur_idx].findCds(type, target);
		
		// check expired cd
		var bCompleted = false;
		
		// if not exist : already done.  
		if ( check_cds.length == 0) { bCompleted = true; }
		
		$.each( check_cds, function ( i, cd) {
			if ( $.now() > cd.endtime.getTime() ) {
				bCompleted = true;
				return false;	// exit each
			}
		});
		
		return bCompleted;
	},
	/*
		///////////////   Sols   
	*/
	
	
	updateSols: function(sols) {
		this.cstls[this.cur_idx].updateSols(sols);
	},
	
	getSolnum:  function(soltype) {
		return this.cstls[this.cur_idx].getSolnum(soltype);
	},
	
	getCurSols:  function() {
		return this.cstls[this.cur_idx].getSols();
	},
	
	/*
		///////////////   H update  
	*/
	
	updateHF : function(h, f ) {
		this.cstls[this.cur_idx].updateHF(h,f); 
	},
	
	updateHntingableHs : function(hs) {
		this.cstls[this.cur_idx].updateHntingableHs(hs);
	},
	updateAllHs : function(hs) {
		this.cstls[this.cur_idx].updateAllHs(hs);
	},
	
	getbestH: function() {
		return this.cstls[this.cur_idx].getbestH();
	},
	 
	 /*
		cstl position ( x, y)
	 */
	getCstlPos: function(index) {
		return { x: this.cstls[index].x , y:this.cstls[index].y} ;
	},
	/*
		study
		
	*/
	
	updateStudies: function(studies) {
		this.cstls[this.cur_idx].updateStudies(studies);
		
		// noty view 
		this.uiView.showStudies(this.cur_idx ,this.cstls[this.cur_idx].studies );
	},
	
	getCdsByType: function(type ) {
		var all_cds = [];
		var i=0;
		// gather all cds.
		for (i=0; i < this.cstls.length; i ++ ) {
			all_cds.concat( this.cstls[i].cds);
		}

		return all_cds.filter ( function (el){  return el.target == type;});
		
	},
	
	/*
		timer 
	*/
	
	descCds: function() {
		var self = this;
		$.each( this.cstls , function(i, cstl) {
			var cds = cstl.getCds();  //cstl.get cds .
			if ( ! cds ) return;
			
			  $.each( cds, function (_,cd){
			  		cd.secs = Math.round((cd.endtime.getTime() - $.now()) / 1000 );
			  		if ( cd.secs < 0 ) {
			  			if ( cd.cdtype == CDB.CDS.ATT ) {  
			  				// mark done
			  				cd.done = true;
			  			}
			  		}
			  });
			 self.uiView.updateCDs(i, cds);		
		})
	},
};

